package com.zhima.sdk.utils;

import android.util.Base64;

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by librabin on 16/11/15.
 */

public class ZMEncryptUtil {

    public static String KEY = "pz5HWbkVzNLPmMpiuc3pLzFZmJvcKRj5";




    public static String mdEncrypt(String str) {
        String str1 = System.currentTimeMillis() + 120000 + "";
        String str2 = getRandomString(13);
        String str3 = KEY;
        String str4 = encryptMD5ToString(str1 + str2 + str3).toLowerCase();
        //待加密内容base64转码为String
        String str5 = new String(Base64.encode(str.getBytes(), Base64.NO_WRAP));

        // 5用4异或
        String str6_1 = doEor(str5, str4);

        String str6_2 = doEor(str1, str2);

        String str6_3 = doEor(str2, str3);

        String finalStr = new String(Base64.encode((str6_1 + str6_2 + str6_3).getBytes(), Base64.NO_WRAP));

        return finalStr;


    }


    /**
     * 解密
     *
     * @param str
     * @return
     */
    public static String mdDecrypt(String str) {
        String finalStr = new String(Base64.decode(str.getBytes(), Base64.NO_WRAP));
        String str2 = KEY;
        String str3_1 = doEor(finalStr.substring(finalStr.length() - 13), str2);
        String str3_2 = doEor(finalStr.substring(finalStr.length() - 26, finalStr.length() - 13), str3_1);
        String str3_3 = encryptMD5ToString(str3_2 + str3_1 + str2).toLowerCase();

        String testStr = doEor(finalStr.substring(0, finalStr.length() - 26), str3_3);

        String testStr2 = new String(Base64.decode(testStr.getBytes(), Base64.NO_WRAP));


        return testStr2;
    }


    private static String doEor(String str1, String str2) {
        char[] array1 = str1.toCharArray();
        char[] array2 = str2.toCharArray();
        char[] array3 = new char[array1.length];

        for (int i = 0; i < array1.length; i++) {
            array3[i] = (char) (array1[i] ^ array2[i % str2.length()]);
        }

        return new String(array3);

    }


    private static String getRandomString(int length) { //length表示生成字符串的长度
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }



    /**
     * MD5 加密
     *
     * @param data 明文字符串
     * @return 16 进制密文
     */
    public static String encryptMD5ToString(final String data) {
        return encryptMD5ToString(data.getBytes());
    }

    /**
     * MD5 加密
     *
     * @param data 明文字节数组
     * @return 16 进制密文
     */
    public static String encryptMD5ToString(final byte[] data) {
        return bytes2HexString(encryptMD5(data));
    }


    /**
     * MD5 加密
     *
     * @param data 明文字节数组
     * @return 密文字节数组
     */
    public static byte[] encryptMD5(final byte[] data) {
        return hashTemplate(data, "MD5");
    }




    /**
     * Base64 编码
     *
     * @param input 要编码的字节数组
     * @return Base64 编码后的字符串
     */
    public static String base64Encode2String(final byte[] input) {
        return Base64.encodeToString(input, Base64.NO_WRAP);
    }



    private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    private static String bytes2HexString(final byte[] bytes) {
        if (bytes == null) return null;
        int len = bytes.length;
        if (len <= 0) return null;
        char[] ret = new char[len << 1];
        for (int i = 0, j = 0; i < len; i++) {
            ret[j++] = hexDigits[bytes[i] >>> 4 & 0x0f];
            ret[j++] = hexDigits[bytes[i] & 0x0f];
        }
        return new String(ret);
    }


    /**
     * hash 加密模板
     *
     * @param data      数据
     * @param algorithm 加密算法
     * @return 密文字节数组
     */
    private static byte[] hashTemplate(final byte[] data, final String algorithm) {
        if (data == null || data.length <= 0) return null;
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            md.update(data);
            return md.digest();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }




    public static String getBasicBase64(String deviceId) {
        try {
            String pwd = encryptMD5ToString(deviceId+ KEY).toLowerCase();
            String basic = deviceId + ":" + pwd;
            return "Basic "+ Base64.encodeToString(basic.getBytes(), Base64.NO_WRAP);


        } catch (Exception e) {
            return "";
        }

    }


    private static final String IV_STRING = "justdoit043&d_ha";
    private static final String charset = "UTF-8";

    public static String aesEncryptString(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        byte[] contentBytes = content.getBytes(charset);
        byte[] keyBytes = key.getBytes(charset);
        byte[] encryptedBytes = aesEncryptBytes(contentBytes, keyBytes);
        return Base64.encodeToString(encryptedBytes, Base64.NO_WRAP);
    }

    public static String aesDecryptString(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        byte[] encryptedBytes = Base64.decode(content, Base64.NO_WRAP);

        byte[] keyBytes = key.getBytes(charset);
        byte[] decryptedBytes = aesDecryptBytes(encryptedBytes, keyBytes);
        return new String(decryptedBytes, charset);
    }

    public static byte[] aesEncryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        return cipherOperation(contentBytes, keyBytes, Cipher.ENCRYPT_MODE);
    }

    public static byte[] aesDecryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        return cipherOperation(contentBytes, keyBytes, Cipher.DECRYPT_MODE);
    }

    private static byte[] cipherOperation(byte[] contentBytes, byte[] keyBytes, int mode) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");

        byte[] initParam = IV_STRING.getBytes(charset);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(mode, secretKey, ivParameterSpec);

        return cipher.doFinal(contentBytes);
    }



}
